<?php

namespace Frieza\Modules\Newtag\Controllers;

use App\Http\Controllers\Controller;
use App\Pockets\GridDataModel as pGridDataModel;
use Doraemon\model\Tag\NewTagRelation;
use Doraemon\service\Tag\TagList;
use Doraemon\service\Tag\TagRelation as sTagRelation;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Widgets\Form;
use Encore\Admin\Widgets\Tab;
use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;
use Doraemon\cache\Queue;
use Doraemon\model\NewTag\Tag as dbTag;
use Doraemon\model\NewTag\TagRelation;
use Doraemon\model\NewTag\OperationTagContent;


class TagController extends Controller
{

    const PAGE_SIZE = 20;

    const LEVEL_COLOR = [
        1 => '#DC143C',
        2 => '#FFA500',
        3 => '#FFFF00',
        4 => '#7FFF00',
        5 => '#00FFFF',
        6 => '#4169E1',
        7 => '#800080'
    ];

    public function list(Request $request, Content $content)
    {
        $params = $request->all();
        $params['page'] = $request->input('page', 1);
        $params['per_page'] = $request->input('per_page', 100);
        if(!isset($params['level'])) {
            $request->merge(['level'=>$params['level']]);
        }

        return $content
            ->header('标签列表')
            ->breadcrumb(
                [
                    'text' => '标签列表',
                    'url'  => '/newtag/list'
                ]
            )
            ->body(self::listAction($params));
    }


    private static function listAction($params = [])
    {

        $data = TagList::getTagList($params);

        $tags_data = $data['data'];

        //组装层级信息
        $tag_ids = (array) array_column($tags_data, 'id');
        $tags_name = (array) array_column($tags_data, 'tag');

        //获取统计信息
        $week = date('Y-W', time() - 86400*7);
        $counts = OperationTagContent::getContentCountsByTags($week, $tags_name);

        $tag_levels = TagList::getLevelsForTags($tag_ids);
        $parent_ids = array_unique(array_reduce($tag_levels, 'array_merge', array()));
        $parent_tags = dbTag::getAllByWhere([
            'tag_status' => dbTag::STATUS_NORMAL,
            'id' => $parent_ids
        ], ['id', 'tag']);
        $parent_tags_format = [];
        if($parent_tags && is_array($parent_tags)) {
            foreach($parent_tags as $tag) {
                $parent_tags_format[$tag['id']] = $tag['tag'];
            }
        }

        if($tags_data && is_array($tags_data)) {
            foreach($tags_data as &$tag_info) {
                $level_str = '';
                $level_ids = array_reverse($tag_levels[$tag_info['id']]);
                if ($level_ids && is_array($level_ids)) {
                    foreach ($level_ids as $level) {
                        $level_str .= $parent_tags_format[$level] . '/';
                    }
                } else {
                    $level_str = '--';
                }
                $tag_info['tag_levels'] = $level_str;
                $tag_info['count'] = $counts[$tag_info['tag']] ? : '-';
            }

        }

        $gridModel = new pGridDataModel($tags_data, $data['total'], [
            'perPage' => $params['per_page'],
        ]);


        $listGrid = Admin::grid($gridModel, function (Grid $grid) {
            $grid->disableExport();
            $grid->disableRowSelector();
            $grid->expandFilter();
            $grid->paginate(100);

            $grid->actions(function (Grid\Displayers\Actions $actions){
                $actions->disableDelete();
            });

            // 筛选项
            $grid->filter(function (Grid\Filter $filter) {
                $filter->disableIdFilter();
                $filter->column(1 / 2, function ($filter) {
                    $filter->equal('tag', '标签名称')->placeholder('请输入标签名称');
                });
            });
            $grid->column('id');
            $grid->column('tag', '标签名')->display(function() {
                $str = '';
                for ($i = 1; $i <= $this->deep; $i++) {
                    $str = "<button class='btn btn-small disabled' style='background-color:".self::LEVEL_COLOR[$i]."'>$i 级标签</button>&nbsp;&nbsp;";
                }
                return $str.$this->tag;
            })->width(200);
            $grid->column('tag_alias', '别名')->display(function () {
                return self::stringToArr($this->tag_alias);
            })->label('default')->width(200);

            $grid->column('tag_levels', '标签层级关系');
            $grid->column('addtime', '标签时间')->display(function() {
                return "创建时间：".$this->addtime."<br/>最后自改时间".$this->edittime;
            });
            $grid->column('admin_id', '标签最后修改人')->display(function() {
                return Admin::user()->find($this->admin_id)->name;
            });

            $grid->column('count', '内容数')->display(function () {
                $week = date('Y-W', time() - 86400*7);
                return "<a href='https://metabase.haohaozhu.me/question/1932?week=".$week."&tag=$this->tag' target='_blank'>".$this->count."</a>";
            });

            $grid->column('tagRelation', '各场景是否生效')->display(function () {
                return self::RTshow($this->tagRelation ?? []);
            });

        });

        return $listGrid;
    }


    public function edit($id = 0, Content $content)
    {
        $tab = new Tab();
        if ($id > 0) {
            $title = '标签编辑';
        } else {
            $title = '创建标签';
        }
        $tab->add("$title", $this->editAction($id));
        return $content
            ->header('标签管理')
            ->breadcrumb(
                [
                    'text' => '标签列表',
                    'url'  => '/newtag/list'
                ],
                ['text' => "$title"]
            )
            ->body($tab);
    }

    private function editAction($id = 0)
    {

        if ($id > 0) {
            $info = TagList::getInfoByTagId($id);
            $info['deep'] = $info['deep']."级标签";
            $info['parent_id'] = TagList::getInfoByTagId($info['parent_id'])['tag'];

            // 获取已有的关联标签，重组成规定格式
            $tagrelationData = sTagRelation::getInfoByid($id);
            // 组装全部的数据
            $allinfo = TagList::getAllRelationInfo($info, $tagrelationData);
            $form = new Form($allinfo);
            $form->hidden('id');
            $form->text('tag', '标签名')->readonly();
        } else {
            $form = new Form();
            $form->text('tag', '标签名')->required('不能为空');
        }
        $form->tags('tag_alias', '别名');

        if($id == 0) {
            $form->select('deep', '标签等级')->options('/admin/newtag/list/edit/tagtype')
                ->load('parent_id', '/admin/newtag/list/edit/tagtype')
                ->required('不能为空');

            $form->select('parent_id', '父级标签');
        } else {
            $form->text('deep', '标签级别')->readonly();
            $form->text('parent_id', '父级标签')->readonly();
        }


        // 用来编写规则
        foreach (TagRelation::RELATION_TYPE as $key => $value) {
            $form->fieldset(TagRelation::RELATION_TYPE[$key], function (Form $form) use ($key) {
                $form->hidden("relation_type.$key")
                    ->options(TagRelation::RELATION_TYPE)
                    ->default($key);
                $form->fieldChange("rule_type.$key", "规则类型", $form)
                    ->default(TagRelation::RELATION_TYPE_VALID_DEFAULE_VALUE[$key])
                    ->options(TagRelation::RULE_TYPE)
                    ->required()
                    ->callableMap([
                        TagRelation::RELATION_RULE_TYPE_NEVER_NO_EXPIRES => function (Form $form) {
                        },
                        TagRelation::RELATION_RULE_TYPE_NEVER_EXPIRES    => function (Form $form) {
                        },
                        TagRelation::RELATION_RULE_TYPE_EXPIRES_TIME     => function (Form $form) use ($key) {
                            $form->radio("expires_repeat_type." . $key, "是否重复指定时间")
                                ->options(TagRelation::REPEAT_TYPE)
                                ->default(TagRelation::REPEAT_TYPE_ON)
                                ->help("每年重复的数据请不要跨年，跨年请转化成不跨年的另一种指定时间规则类型，每年11月至第二年1月无效的标签等效于每年1月到11月有效的标签");
                            $form->dateRange("starttime.$key", "endtime.$key", "选择时间");
                        },
                        TagRelation::RELATION_RULE_TYPE_NO_EXPIRES_TIME  => function (Form $form) use ($key) {
                            $form->radio("no_expires_repeat_type." . $key, "是否重复指定时间")
                                ->options(TagRelation::REPEAT_TYPE)
                                ->default(TagRelation::REPEAT_TYPE_ON)
                                ->help("每年重复的数据请不要跨年，跨年请转化成不跨年的另一种指定时间规则类型，每年11月至第二年1月无效的标签等效于每年1月到11月有效的标签");
                            $form->dateRange("starttime.$key", "endtime.$key", '选择时间');
                        }
                    ]);
            });
        }
        $form->action('/admin/newtag/list/save');

        return $form;
    }

    /**
     * 保存
     *
     * @param Request $request
     */
    public function saveSubmit(Request $request)
    {
        $params = $request->all();

        // 判断标签名是否重复
        $res = TagList::getInfoByTagName($params['tag'], '*');
        if ($res != NULL) {
            if(isset($params['id']) && $params['id'] != $res['id']) {
                $error = new MessageBag([
                    'title' => '标签名重复',
                ]);
                return back()->with(compact('error'));
            }
            if (!isset($params['id']) && $params['tag'] == $res['tag']) {
                $error = new MessageBag([
                    'title' => '标签名重复',
                ]);
                return back()->with(compact('error'));
            }
        }

        try {
            TagList::saveData($params);

            //重新排序
            $tags = dbTag::getAllByWhere([
                'tag_status' => dbTag::STATUS_NORMAL
            ], ['id', 'tag', 'parent_id', 'deep']);
            $list = $this->getTree($tags);
            if($list && is_array($list)) {
                $sort = 1;
                foreach($list as $tag) {
                    dbTag::update(['tag_sort' => $sort], [
                        'id' => $tag['id']
                    ]);
                    $sort++;
                }
            }

            return back()->with('success', new MessageBag([
                'title' => '操作成功'
            ]));
        } catch (\Exception $e) {
            return back()->with('error', new MessageBag([
                'title' => $e->getMessage()
            ]));
        }
    }

    public function getTree($tags, $pid = 0, $level = 1)
    {
        static $list = [];
        if($tags && is_array($tags)) {
            $value['tag_levels'] = '';
            foreach ($tags as $key => $value) {
                if ($value['parent_id'] == $pid) {
                    $value['deep'] = $level;
                    //把数组放到list中
                    $list[] = $value;
                    unset($tags[$key]);
                    $this->getTree($tags, $value['id'], $level + 1);
                }
            }
        }

        return $list;
    }

    /**
     * 获取父标签
     *
     * @param Request $request
     * @return void
     */
    public function getTagType(Request $request)
    {
        $deep = $request->input('q');
        if(!isset($deep)) {
            $max_deep = (int) dbTag::max('deep', [
                'tag_status' => dbTag::STATUS_NORMAL
            ]);
            for($i = 1; $i <= $max_deep; $i++) {
                $deeps[$i-1]['id'] = $i;
                $deeps[$i-1]['tag'] = $i.'级标签';
            }
            $result = $deeps;

        } else {
            $result = dbTag::getAllByWhere([
                "tag_status" => dbTag::STATUS_NORMAL,
                'deep' => $deep - 1,
                'deep[!]' => 0
            ]);
        }

        $categories = array_map(function ($category) {
            return [
                "id"   => $category["id"],
                "text" => $category["tag"]
            ];
        }, $result);

        return response()->json($categories);
    }

    /**
     * 获取子标签
     *
     * @param Request $request
     * @return void
     */
    public function getTagChildren(Request $request)
    {
        $deep = $request->all()['q'];
        if($deep == '') {
            $max_deep = (int) dbTag::max('deep', [
                'tag_status' => dbTag::STATUS_NORMAL
            ]);
            for($i = 1; $i <= $max_deep; $i++) {
                $deeps[$i-1]['id'] = $i;
                $deeps[$i-1]['tag'] = $i.'级标签';
            }
            $result = $deeps;

        } else {
            $result = dbTag::getAllByWhere([
                "tag_status" => dbTag::STATUS_NORMAL,
                "deep" => $deep
            ]);
        }
        $categories = array_map(function ($category) {
            return [
                "id"   => $category["id"],
                "text" => $category["tag"]
            ];
        }, $result);

        return response()->json($categories);

    }


    /**
     * 删除
     * @param $id
     * @return void
     */
    public function del($id)
    {
        $tag_info = dbTag::getOneByWhere(['id'=>$id]);
        dbTag::delTagById($id);
        if($tag_info && is_array($tag_info)) {
            Queue::insertQueue('queue/Search/AddLexiconWord', array(
                'word' => $tag_info['tag'],
                'type' => "delete",
                'origin_word' => ""
            ), Queue::QUEUE_DORAEMON);
        }

        return response()->json([
            'status'  => true,
            'message' => "操作成功",
        ]);
    }

    private static function stringToArr($str = '')
    {
        $format = [];
        if ($str) {
            if (strpos($str, ',')) {
                $tagAliasArr = explode(',', $str);
                foreach ($tagAliasArr as $key => $value) {
                    $format[$value] = $value;
                }
            } else {
                $format[$str] = $str;
            }
        }
        return $format;
    }

    private static function RTshow($relations)
    {
        $relations = array_column($relations, null, 'relation_type');
        $str = '<dl class="dl-horizontal">';
        foreach (NewTagRelation::RELATION_TYPE as $relationType => $relationTypeName) {
            $dd = NewTagRelation::RULE_TYPE[$relations[$relationType]['rule_type']] ?? NewTagRelation::RULE_TYPE[NewTagRelation::RELATION_TYPE_VALID_DEFAULE_VALUE[$relationType]];
            if (in_array($relations[$relationType]['rule_type'], [
                NewTagRelation::RELATION_RULE_TYPE_EXPIRES_TIME,
                NewTagRelation::RELATION_RULE_TYPE_NO_EXPIRES_TIME
            ])) {
                $dd .= "/" . NewTagRelation::REPEAT_TYPE[$relations[$relationType]['repeat_type']] . "<br/>";
                $dd .= date('Y-m-d', strtotime($relations[$relationType]['starttime_year'] . $relations[$relationType]['starttime_day'])) . '至'
                    . date('Y-m-d', strtotime($relations[$relationType]['endtime_year'] . $relations[$relationType]['endtime_day']));
            }
            $str .= "<dt>{$relationTypeName}</dt><dd>{$dd}</dd>";
        }
        $str .= '</dl>';
        return $str;
    }



}
